package com.zerowidth.moc.web.controller.serviceimpl;

import com.zerowidth.db.DBHelper;
import com.zerowidth.db.base.SqlResult;
import com.zerowidth.db.bean.*;
import com.zerowidth.db.op.*;
import com.zerowidth.db.utils.TimeUtils;
import com.zerowidth.moc.web.bean.MoneyBean;
import com.zerowidth.moc.web.bean.StatUserBean;
import com.zerowidth.moc.web.controller.service.StatServiceV2;
import com.zerowidth.moc.web.resp.ResCode;
import com.zerowidth.moc.web.resp.ResultBean;
import com.zerowidth.moc.web.resp.helper.ResponseCreator;
import com.zerowidth.moc.web.utils.CollectionUtils;
import com.zerowidth.moc.web.utils.StringUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import jakarta.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.UUID;

@Service
public class StatServiceImplV2 implements StatServiceV2 {

    @Override
    public ResponseEntity<ResultBean<List<PayCountBean>>> getStatIncoming() {

        List<PayCountBean> list = new ArrayList<>();

        {
            //今日收入
            PayCountBean totalDay = queryPayCount(TimeUtils.getTodayStart(), TimeUtils.getTodayEnd(), "");
            PayCountBean wxDay = queryPayCount(TimeUtils.getTodayStart(), TimeUtils.getTodayEnd(), "wxpay");
            PayCountBean aliDay = queryPayCount(TimeUtils.getTodayStart(), TimeUtils.getTodayEnd(), "alipay");
            list.add(totalDay);
            list.add(wxDay);
            list.add(aliDay);
        }

        {
            //昨日收入
            PayCountBean totalDay = queryPayCount(TimeUtils.getYesterdayStart(), TimeUtils.getYesterdayEnd(), "");
            PayCountBean wxDay = queryPayCount(TimeUtils.getYesterdayStart(), TimeUtils.getYesterdayEnd(), "wxpay");
            PayCountBean aliDay = queryPayCount(TimeUtils.getYesterdayStart(), TimeUtils.getYesterdayEnd(), "alipay");
            list.add(totalDay);
            list.add(wxDay);
            list.add(aliDay);
        }

        {
            //本月收入
            Calendar calendar = Calendar.getInstance();
            calendar.set(Calendar.DAY_OF_MONTH, 1);
            String start = TimeUtils.convertYYYYMMDD2(calendar.getTime().getTime()) + " 00:00:00";
            calendar.add(Calendar.MONTH, 1);
            String end = TimeUtils.convertYYYYMMDD2(calendar.getTime().getTime()) + " 00:00:00";

            PayCountBean totalDay = queryPayCount(start, end, "");
            PayCountBean wxDay = queryPayCount(start, end, "wxpay");
            PayCountBean aliDay = queryPayCount(start, end, "alipay");
            list.add(totalDay);
            list.add(wxDay);
            list.add(aliDay);
        }

        {
            //上月收入
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.MONTH, -1);
            calendar.set(Calendar.DAY_OF_MONTH, 1);
            String start = TimeUtils.convertYYYYMMDD2(calendar.getTime().getTime()) + " 00:00:00";
            calendar.add(Calendar.MONTH, 1);
            calendar.set(Calendar.DAY_OF_MONTH, 1);
            String end = TimeUtils.convertYYYYMMDD2(calendar.getTime().getTime()) + " 00:00:00";

            PayCountBean totalDay = queryPayCount(start, end, "");
            PayCountBean wxDay = queryPayCount(start, end, "wxpay");
            PayCountBean aliDay = queryPayCount(start, end, "alipay");
            list.add(totalDay);
            list.add(wxDay);
            list.add(aliDay);
        }

        {
            //全部收入
            Calendar calendar = Calendar.getInstance();
            calendar.set(Calendar.YEAR, 2010);
            String start = TimeUtils.convertYYYYMMDD2(calendar.getTime().getTime()) + " 00:00:00";
            calendar.set(Calendar.YEAR, 2030);
            String end = TimeUtils.convertYYYYMMDD2(calendar.getTime().getTime()) + " 23:59:59";

            PayCountBean totalDay = queryPayCount(start, end, "");
            PayCountBean wxDay = queryPayCount(start, end, "wxpay");
            PayCountBean aliDay = queryPayCount(start, end, "alipay");
            list.add(totalDay);
            list.add(wxDay);
            list.add(aliDay);
        }

        {
            //今年收入
            Calendar calendar = Calendar.getInstance();
            calendar.set(Calendar.MONTH, 0);
            calendar.set(Calendar.DAY_OF_MONTH, 1);
            String start = TimeUtils.convertYYYYMMDD2(calendar.getTime().getTime()) + " 00:00:00";
            calendar.add(Calendar.YEAR, 1);
            String end = TimeUtils.convertYYYYMMDD2(calendar.getTime().getTime()) + " 00:00:00";

            PayCountBean totalDay = queryPayCount(start, end, "");
            PayCountBean wxDay = queryPayCount(start, end, "wxpay");
            PayCountBean aliDay = queryPayCount(start, end, "alipay");
            list.add(totalDay);
            list.add(wxDay);
            list.add(aliDay);
        }

        {
            //上年收入
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.YEAR, -1);
            calendar.set(Calendar.MONTH, 0);
            calendar.set(Calendar.DAY_OF_MONTH, 1);
            String start = TimeUtils.convertYYYYMMDD2(calendar.getTime().getTime()) + " 00:00:00";
            calendar.add(Calendar.YEAR, 1);
            String end = TimeUtils.convertYYYYMMDD2(calendar.getTime().getTime()) + " 00:00:00";

            PayCountBean totalDay = queryPayCount(start, end, "");
            PayCountBean wxDay = queryPayCount(start, end, "wxpay");
            PayCountBean aliDay = queryPayCount(start, end, "alipay");
            list.add(totalDay);
            list.add(wxDay);
            list.add(aliDay);
        }

        return ResponseCreator.creatOk(list, ResCode.CODE_OK, "查询收入成功");
    }

    private PayCountBean queryPayCount(String startTime, String endTime, String payType) {

        String sql = String.format("SELECT vip_type, count(vip_type) as countValue FROM vip_order " +
                "WHERE vip_type <> 100 and pay_success = 1 and create_time >= '%s' " +
                "AND create_time <= '%s' ", startTime, endTime);

        if (StringUtils.isNotEmpty(payType)) {
            sql += String.format(" AND order_type LIKE '%s' ", payType);
        }
        sql += String.format(" GROUP BY vip_type ");

        SqlResult sr = DBHelper.executeQueryEx(sql);

        if (sr == null) {
            return null;
        }

        PayCountBean bean = new PayCountBean();

        try {
            while (sr.rs.next()) {
                int vip_type = sr.rs.getInt("vip_type");
                int count = sr.rs.getInt("countValue");
                switch (vip_type) {
                    case 1:
                        bean.count_day = count;
                        break;
                    case 2:
                        bean.count_month = count;
                        break;
                    case 3:
                        bean.count_quarter = count;
                        break;
                    case 4:
                        bean.count_half_year = count;
                        break;
                    case 5:
                        bean.count_year = count;
                        break;
                    case 6:
                        bean.count_forever = count;
                        break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        sr.close();

        return bean;
    }

    @Override
    public ResponseEntity<ResultBean<List<OrderBean>>> getOrderList(String startTime, String endTime) {

        String sql;
        if (StringUtils.isEmpty(endTime)) {
            sql = String.format("SELECT * FROM vip_order WHERE vip_type <> 100 and create_time >= '%s'", startTime);
        } else {
            sql = String.format("SELECT * FROM vip_order WHERE vip_type <> 100 and create_time >= '%s' AND create_time <= '%s'", startTime, endTime);
        }

        SqlResult sr = DBHelper.executeQueryEx(sql);
        if (sr == null || sr.rs == null) {
            return ResponseCreator.creatOk(null, ResCode.CODE_OK, "查询订单记录成功");
        }

        List<OrderBean> list = new ArrayList<>();
        try {
            while (sr.rs.next()) {
                OrderBean orderBean = new OrderBean();
                orderBean.id = sr.rs.getInt("id");
                orderBean.vip_type = sr.rs.getInt("vip_type");
                orderBean.amount = sr.rs.getFloat("amount");
                orderBean.price = sr.rs.getFloat("price");
                orderBean.subject_value = sr.rs.getString("subject_value");
                orderBean.pay_success = sr.rs.getBoolean("pay_success");
                //统计数据，不需要知道订单信息，避免安全问题
                //orderBean.order_info = sr.rs.getString("order_info");
                orderBean.create_time = sr.rs.getString("create_time");
                orderBean.order_type = sr.rs.getString("order_type");
                orderBean.user_id = sr.rs.getString("user_id");
                orderBean.out_trade_no = sr.rs.getString("out_trade_no");

                list.add(orderBean);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return ResponseCreator.creatOk(list, ResCode.CODE_OK, "查询订单记录成功");
    }

    @Override
    public ResponseEntity<ResultBean<StatUserBean>> getUserStat(String start_time, String end_time) {

        StatUserBean statUserBean = new StatUserBean();
        statUserBean.start_user_total = MockStatUserDB.countByUpdateTime(start_time, end_time);
        statUserBean.new_user_total = MockStatUserDB.countByCreateTime(start_time, end_time);
        statUserBean.login_count = UserDB.count(start_time, end_time);
        statUserBean.exchange_count = ExchangeRecordDB.count(start_time, end_time);
        statUserBean.sms_count = SMS_DB.count(start_time, end_time);
        statUserBean.collect_count = CollectDB.count(start_time, end_time);
        statUserBean.collect_user_count = CollectDB.countUser(start_time, end_time);
        statUserBean.report_count = ReportDB.count(start_time, end_time);
        statUserBean.order_no_pay = VipOrderDB.countNoPay(start_time, end_time);
        statUserBean.sign_count = SignRecordDB.count(start_time.split(" ")[0]);

        return ResponseCreator.creatOk(statUserBean, ResCode.CODE_OK, "查询统计数据成功");
    }

    @Override
    public ResponseEntity<ResultBean<MoneyBean>> getStatMoney() {
        MoneyBean moneyBean = new MoneyBean();
        moneyBean.today_money = queryMoney(TimeUtils.getTodayStart(), TimeUtils.getTodayEnd());
        moneyBean.yesterday_money = queryMoney(TimeUtils.getYesterdayStart(), TimeUtils.getYesterdayEnd());
        moneyBean.month_money = queryMoney(TimeUtils.getMonthStart(), TimeUtils.getMonthEnd());
        moneyBean.last_month_money = queryMoney(TimeUtils.getLastMonthStart(), TimeUtils.getLastMonthEnd());
        moneyBean.total_money = queryMoney(null, null);
        moneyBean.this_year_money = queryMoney(TimeUtils.getYearStart(), TimeUtils.getYearEnd());
        moneyBean.last_year_money = queryMoney(TimeUtils.getLastYearStart(), TimeUtils.getLastYearEnd());

        return ResponseCreator.creatOk(moneyBean, ResCode.CODE_OK, "查询统计数据成功");
    }

    private float queryMoney(String startTime, String endTime) {
        String sql = String.format("select sum(amount) as money from mockDB.vip_order\n" +
                "where vip_type <> 100 and pay_success = 1\n" +
                "and create_time >= '%s'\n" +
                "and create_time < '%s'", startTime, endTime);

        if (startTime == null && endTime == null) {
            sql = String.format("select sum(amount) as money from mockDB.vip_order\n" +
                    "where vip_type <> 100 and pay_success = 1\n");
        }

        SqlResult sr = DBHelper.executeQueryEx(sql);

        if (sr == null) {
            return 0;
        }

        try {
            if (sr.rs.next()) {
                int money = sr.rs.getInt("money");
                return money;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            sr.close();
        }

        return 0;
    }

    @Override
    public ResponseEntity<ResultBean<String>> createActiveCode(int vipType) {

        String uuid = UUID.randomUUID().toString().toUpperCase();

        String activeCode = StringUtils.subSequence(uuid, 0, 7);

        if (vipType == 1) {
            activeCode = "D" + activeCode;
        } else if (vipType == 2) {
            activeCode = "M" + activeCode;
        } else if (vipType == 3) {
            activeCode = "Q" + activeCode;
        } else if (vipType == 4) {
            activeCode = "H" + activeCode;
        } else if (vipType == 5) {
            activeCode = "Y" + activeCode;
        } else if (vipType == 6) {
            activeCode = "F" + activeCode;
        }

        ActiveDB.insert(activeCode, vipType);

        return ResponseCreator.creatOk(activeCode, ResCode.CODE_OK, "查询统计数据成功");
    }

    public ResponseEntity<ResultBean<Void>> unbind(HttpServletRequest request, String pwd, String unbind_key) {
        String stat_id = request.getHeader("stat_id");

        List<AppConfigBean> list = AppConfigDB.getAppConfigData("");

        AppConfigBean bean = CollectionUtils.findFirst(list, new CollectionUtils.Function1<AppConfigBean, Boolean>() {
            @Override
            public boolean accept(AppConfigBean appConfigBean) {
                return StringUtils.equals(appConfigBean.config_key, "unbind_pwd");
            }
        });

        if (bean == null) {
            return ResponseCreator.creatOk(null, ResCode.CODE_ERR_UNKNOWN, "解绑失败，密码配置错误");
        }

        if (!StringUtils.equals(bean.config_value, pwd)) {
            return ResponseCreator.creatOk(null, ResCode.CODE_ERR_UNKNOWN, "解绑失败，密码错误");
        }

        UserBean userBean = UserDB.findUserByKey(unbind_key);

        if (userBean == null) {
            return ResponseCreator.creatOk(null, ResCode.CODE_ERR_UNKNOWN, "解绑失败，账号不存在");
        }

        MockStatUserDB.clearDeviceInfo(userBean.user_id);

        return ResponseCreator.creatOk(null, ResCode.CODE_OK, "解绑成功");
    }

    @Override
    public ResponseEntity<ResultBean<Void>> lever_up(HttpServletRequest request, String user_id, int vipType) {

        if (StringUtils.length(user_id) < 8) {
            return ResponseCreator.creatOk(null, ResCode.CODE_ERR_UNKNOWN, "升级失败，用户ID长度至少8位");
        }

        if (UserDB.countUserByUserIdLike(user_id) <= 0) {
            return ResponseCreator.creatOk(null, ResCode.CODE_ERR_UNKNOWN, "升级失败，用户ID不存在");
        }

        UserBean userBean = UserDB.findUserByUserIdLike(user_id);

        if (userBean == null) {
            return ResponseCreator.creatOk(null, ResCode.CODE_ERR_UNKNOWN, "升级失败，用户ID不存在");
        }


        if (StringUtils.isEmpty(userBean.vip_start_time)) {
            userBean.vip_start_time = TimeUtils.convert(System.currentTimeMillis(), TimeUtils.TIME_FORMAT_YYYY_MM_DD_HH_MM_SS);
        }

        if (vipType == 6) {
            userBean.vip_end_time = "2099-01-01 00:00:00";
        } else if (vipType == 7) {
            userBean.vip_end_time = "2299-01-01 00:00:00";

            UserDB.updateDingSafeVersion(userBean.user_id, 1);
        }


        UserDB.updateVipType(userBean.user_id, vipType, userBean.vip_start_time, userBean.vip_end_time);

        return ResponseCreator.creatOk(null, ResCode.CODE_OK, "升级成功");
    }

    @Override
    public ResponseEntity<ResultBean<UserQueryBean>> query_user_id(HttpServletRequest request, String key) {

        //查询用户id，模拟查询，可填写手机号、微信昵称、激活码、以旧换新激活码、设备id

        UserBean userBean = UserDB.findUserByPhone(key);

        if (userBean == null) {
            userBean= UserDB.findUserByWxNameLike(key);
        }

        if (userBean == null) {
            userBean= UserDB.findUserByStatId(key);
        }

        if (userBean == null) {
            userBean= UserDB.findUserByWxNameLike(key);
        }

        if (userBean == null) {
            String activeUserId = ActiveDB.findActiveUserId(key);
            if (activeUserId != null) {
                userBean = UserDB.findUserByUserId(activeUserId);
            }
        }

        if (userBean == null) {
            String exchangeUserId = ExchangeRecordDB.findExchangeUserId(key);
            if (exchangeUserId != null) {
                userBean = UserDB.findUserByUserId(exchangeUserId);
            }
        }

        if (userBean != null) {
            UserQueryBean userQueryBean = new UserQueryBean();
            userQueryBean.user_id = userBean.user_id;
            userQueryBean.stat_id = userBean.stat_id;
            userQueryBean.phone_number = userBean.phone_number;
            userQueryBean.nick_name = userBean.nick_name;
            userQueryBean.vip_type = userBean.vip_type;
            userQueryBean.vip_start_time = userBean.vip_start_time;
            userQueryBean.vip_end_time = userBean.vip_end_time;

            return ResponseCreator.creatOk(userQueryBean, ResCode.CODE_OK, "查询会员ID成功");
        }

        return ResponseCreator.creatOk(null, ResCode.CODE_ERR_UNKNOWN, "查询会员ID失败");
    }
}
